package edu.utexas.esel.jgraphpad.archpadplugin.tools;

import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;

import org.jgraph.JGraph;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultPort;
import org.jgraph.graph.PortView;

import com.jgraph.pad.tool.JGraphpadEdgeTool;

import edu.utexas.esel.jgraphpad.archpadplugin.ArchPadPlugin;
import edu.utexas.esel.jgraphpad.archpadplugin.model.Element;
import edu.utexas.esel.jgraphpad.archpadplugin.model.ElementTreeNode;

/**
 * ArchPad edge tool that supports drawing only edges the connect two
 * vertices and one of these vertices represents a connector in an ArchPad
 * model.
 *
 * @author svetoslavganov@mial.utexas.edu
 *
 */
public class ArchPadEdgeTool extends JGraphpadEdgeTool {

	/**
	 * {@inheritDoc}
	 */
	public ArchPadEdgeTool(Object prototype) {
		super(prototype);
	}

	/**
	 * {@inheritDoc}
	 */
	public ArchPadEdgeTool(String name, Object prototype) {
		super(name, prototype);
	}

	@Override
	public void mouseReleased(MouseEvent event) {
		if (current != null && canConnect()) {
		    super.mouseReleased(event);
		} else {
			Rectangle2D dirty = previewView.getBounds();
			previewView = null;

			JGraph graph = getGraphForEvent(event);			
			dirty = graph.toScreen((Rectangle2D) dirty.clone());
			graph.repaint((int) dirty.getX() - 1, (int) dirty.getY() - 1,
				(int) dirty.getWidth() + 2, (int) dirty.getHeight() + 2);
		}
	}

	/**
	 * Returns if the start and current {@link PortView} can be connected.
	 * Connections only between a component and a connector are permitted.
	 *
	 * @return True if can connect the ports, false otherwise.
	 */
	private boolean canConnect() {
		String connectorName =
			ArchPadPlugin.TYPE_DECLARATION_CONNECTOR.getName();

		String startName = getParentModelRootNodeName(start);
		String currentName = getParentModelRootNodeName(current);

		if (startName.equals(connectorName)
				|| currentName.equals(connectorName)) {
            return true;			
		}
		return false;
	}

	/**
	 * Returns the name of the name of the ArchPad element
	 * represented by the parent of the {@link DefaultPort}
	 * represented by the <code>portView</code>.
	 *
	 * @param port The port view.
	 * @return The name of the ArchPad element.
	 */
	private String getParentModelRootNodeName(PortView port) {
		DefaultGraphCell childSource = (DefaultGraphCell) port.getCell();
		DefaultGraphCell source = (DefaultGraphCell) childSource.getParent();
		Element model = (Element) source.getUserObject();
		ElementTreeNode root = (ElementTreeNode) model.getRoot();
		return root.getDeclaration().getName();
	}
}
